﻿using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using TeBigScreenWpf.Common;

namespace TeBigScreenWpf.Views
{
    public enum TeCustomGroupType
    {
        Trapezoidal,
        Top,
        Left,
    }

    internal class TeCustomGroup : ContentControl
    {
        public TeCustomGroupType Type
        {
            get { return (TeCustomGroupType)GetValue(TypeProperty); }
            set { SetValue(TypeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Type.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TypeProperty =
            DependencyProperty.Register("Type", typeof(TeCustomGroupType), typeof(TeCustomGroup), new PropertyMetadata(TeCustomGroupType.Trapezoidal));

        private readonly Brush colorBackGround = Themes.TeCustomGroup.colorBackGround;
        private readonly Brush colorBorder = Themes.TeCustomGroup.colorBorder;
        private readonly Brush colorCorner = Themes.TeCustomGroup.colorCorner;
        private readonly Brush colorText = Themes.TeCustomGroup.colorText;
        private readonly Brush colorCaption = Themes.TeCustomGroup.colorCaption;

        private const int BorderOffset = 12;
        private const double TrapezoidalOffset = 12;
        private const double TextareaRatio = 1.4;

        private readonly FontFamily captionFontFamily;

        private const double MarginBorderWidth = 5;
        private const double BorderWidth = 4;
        private const double CaptainHeight = 40;
        private const double DefaultFontSize = 30;

        private const double DrawBorderWidth = 2;
        private const double DrawRadiusX = 6;
        private const double DrawRadiusY = 6;

        public string Caption
        {
            get { return (string)GetValue(CaptionProperty); }
            set { SetValue(CaptionProperty, value); }
        }

        public static readonly DependencyProperty CaptionProperty =
            DependencyProperty.Register("Caption", typeof(string), typeof(TeCustomGroup), new PropertyMetadata(""));

        public double CaptionThickness
        {
            get { return (double)GetValue(CaptionThicknessProperty); }
            set { SetValue(CaptionThicknessProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CaptionThickness.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CaptionThicknessProperty =
            DependencyProperty.Register("CaptionThickness", typeof(double), typeof(TeCustomGroup), new PropertyMetadata(CaptainHeight));

        public TeCustomGroup()
        {
            this.Margin = new Thickness(MarginBorderWidth);
            this.FontSize = DefaultFontSize;

            captionFontFamily = Application.Current.Resources["font_title"] as FontFamily ?? this.FontFamily;

            this.Loaded += TeCustomGroup_Loaded;
        }

        private void TeCustomGroup_Loaded(object sender, RoutedEventArgs e)
        {
            if (this.Content is FrameworkElement ui)
            {
                ui.Margin =
                    String.IsNullOrWhiteSpace(Caption) ?
                    new Thickness(BorderWidth) :
                    new Thickness(BorderWidth, CaptainHeight, BorderWidth, BorderWidth);
            }
        }

        private Size MeasureString(string candidate)
        {
            FormattedText ft = new FormattedText(candidate, CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
                new Typeface(this.FontFamily, this.FontStyle, this.FontWeight, this.FontStretch),
                this.FontSize, this.Foreground);

            return new Size(ft.Width, ft.Height);
        }

        private void DrawBackground(DrawingContext dc)
        {
            var bounds = new Rect(RenderSize);

            dc.DrawRoundedRectangle(null/*colorBackGround*/, new Pen(colorBorder, DrawBorderWidth),
                bounds, DrawRadiusX, DrawRadiusY);

            PathGeometry four_border_path = new PathGeometry();

            //左上
            {
                PathGeometry path = new PathGeometry();

                path.AddLines(new Point[]
                {
                    new Point(bounds.Left, bounds.Top + BorderOffset),
                    new Point(bounds.Left, bounds.Top),
                    new Point(bounds.Left + BorderOffset, bounds.Top),
                });

                four_border_path.AddGeometry(path);
            }
            //右上
            {
                PathGeometry path = new PathGeometry();

                path.AddLines(new Point[]
                {
                    new Point(bounds.Right - BorderOffset, bounds.Top),
                    new Point(bounds.Right, bounds.Top),
                    new Point(bounds.Right, bounds.Top + BorderOffset),
                });

                four_border_path.AddGeometry(path);
            }
            //左下
            {
                PathGeometry path = new PathGeometry();

                path.AddLines(new Point[]
                {
                    new Point(bounds.Left, bounds.Bottom - BorderOffset),
                    new Point(bounds.Left, bounds.Bottom),
                    new Point(bounds.Left + BorderOffset, bounds.Bottom),
                });

                four_border_path.AddGeometry(path);
            }
            //右下
            {
                PathGeometry path = new PathGeometry();

                path.AddLines(new Point[]
                {
                    new Point(bounds.Right - BorderOffset, bounds.Bottom),
                    new Point(bounds.Right, bounds.Bottom),
                    new Point(bounds.Right, bounds.Bottom - BorderOffset),
                });

                four_border_path.AddGeometry(path);
            }

            //dc.DrawGeometry(null, new Pen(colorCorner, 2), four_border_path);
        }

        private void DrawCaption(DrawingContext dc)
        {
            var bounds = new Rect(RenderSize);

            {
                FormattedText ft = new FormattedText(Caption, CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
                  new Typeface(captionFontFamily, this.FontStyle, this.FontWeight, this.FontStretch),
                  this.FontSize, colorText);

                Rect text_area = new Rect(new Point(bounds.Left + (bounds.Width - ft.Width * TextareaRatio) / 2, 0),
                    new Size(ft.Width * TextareaRatio, CaptionThickness));

                dc.DrawText(ft, new Point(text_area.Left + (text_area.Width - ft.Width) / 2,
                    text_area.Top + (text_area.Height - ft.Height) / 2));
            }
        }

        protected override void OnRender(DrawingContext dc)
        {
            base.OnRender(dc);

            DrawBackground(dc);

            DrawCaption(dc);
        }
    }
}